using System;
using System.Net;
using System.Web.Mvc;
using BrettM.SimpleDemo.WebApp.Models;
using BrettM.SimpleDemo.WebApp.Store;
using BrettM.Web.Http;
using BrettM.Web.Restful;

namespace BrettM.SimpleDemo.WebApp.Controllers
{
    /// <summary>
    /// 
    /// </summary>
    [HandleError]
    public class CustomerController
        : RestController
    {
        private readonly ISimpleDemoStoreFactory _storeFactory;

        /// <summary>
        /// The ctor used to create an instance of the customer controller.
        /// </summary>
        /// <param name="storeFactory">An instance of th store factory</param>
        /// <remarks>
        /// This ctor takes an instance of a store factory allowing methods
        /// to crete instances of the store to perform tasks
        /// </remarks>
        public CustomerController(ISimpleDemoStoreFactory storeFactory)
        {
            _storeFactory = storeFactory;
        }


        /// <summary>
        /// Retyrbs a help page
        /// </summary>
        /// <returns>The base class ViewPage with html describing the methods</returns>
        [Restful("", HttpVerbs.Get)]
        public override ActionResult Help()
        {
            return base.Help();
        }

        /// <summary>
        /// Gets a complete list of customers
        /// </summary>
        /// <returns>A ModelResult with CustomerList with 0 or more Customer objects</returns>
        [Restful("customers", HttpVerbs.Get)]
        public ActionResult GetAllCustomers()
        {
            var store = _storeFactory.CreateStore();
            var customers = store.GetCustomers();
            return new ModelResult<CustomerList>(customers);
        }

        /// <summary>
        /// Adds a new customer to the list of customers
        /// </summary>
        /// <returns>A 201 - Created</returns>
        [Restful("customers", HttpVerbs.Post)]
        [ModelFilter(typeof(NewCustomer), "newCustomer")]
        public ActionResult AddCustomers(NewCustomer newCustomer)
        {
            var store = _storeFactory.CreateStore();
            store.AddCustomer(newCustomer);
            return new HttpCreatedResult("") { };
        }

        /// <summary>
        /// Gets a customer on the specified customer code
        /// </summary>
        /// <param name="customerCode"></param>
        /// <returns>A modol of the customer</returns>
        [Restful("customers/{customerCode}", HttpVerbs.Get)]
        public ActionResult GetCustomer(string customerCode)
        {
            var store = _storeFactory.CreateStore();
            var customer = store.GetCustomer(customerCode);
            return new ModelResult<Customer>(customer);
        }

        /// <summary>
        /// Updates an existing customer with new data
        /// </summary>
        /// <param name="customerCode">The customer code to update</param>
        /// <param name="customer">A customer object in the body</param>
        /// <returns></returns>
        [Restful("customers/{customerCode}", HttpVerbs.Put)]
        [ModelFilter(typeof(Customer), "customer")]
        public ActionResult UpdateCustomer(string customerCode, Customer customer)
        {
            if (customer == null) throw new ArgumentNullException();
            if (customer.Code != customerCode) throw new ArgumentOutOfRangeException();

            var store = _storeFactory.CreateStore();
            store.UpdateCustomer(customer);

            return new HttpResult(HttpStatusCode.OK);
        }

        /// <summary>
        /// Deletes a customer from the collection of customers
        /// </summary>
        /// <param name="customerCode"></param>
        /// <returns>Returns a 200 - OK if succsful or a 4?? - Gone if not found</returns>
        [Restful("customers/{customerCode}", HttpVerbs.Delete)]
        public ActionResult DeleteCustomer(string customerCode)
        {
            var store = _storeFactory.CreateStore();
            if (store.DeleteCustomer(customerCode))
            {
                return new HttpResult(HttpStatusCode.OK);
            }
            else
            {
                return new HttpResult(HttpStatusCode.Gone);
            }

        }

    }
}
